package com.haidong.dao.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Aspect
public class MyAdvice {

    @Pointcut("execution(* com.haidong.dao.BookDao.*(..))")
    private void pt(){}

//    @Before("pt()")
//    public void before(JoinPoint jp){
//        // 通过传入JoinPoint对象来获取原方法的参数数组
//        Object[] args = jp.getArgs();
//        System.out.println(Arrays.toString(args));
//        System.out.println("before advice");
//    }

//    @After("pt()")
//    public void after(){
//        System.out.println("after advice");
//    }
//
    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice");

        Object[] arg = pjp.getArgs();
        System.out.println("当前在环绕通知控制中,原本传入的参数是:" + Arrays.toString(arg));
        // proceed无参的话就遵循原参数,也可以传参数替换原本参数
        System.out.println("我在环绕通知中修改了参数,现在参数是314,这个可以在不改动原代码的情况下拦截过滤参数,增强健壮性");
        Object ret = pjp.proceed(new Object[]{314});

        System.out.println("around after advice");
        return ret;
    }

    /**
     * 方法后通知可以获取返回值,但是和环绕通知写法不同
     * 要在注解中加参数,还要在切入点方法中加返回值参数(如果有JoinPoint参数放在首位)
     * @param jp
     * @param ret
     */
    @AfterReturning(value = "pt()",returning = "ret")
    public void afterReturning(JoinPoint jp,Object ret){
        System.out.println("afterReturning advice");
    }

//    @AfterThrowing("pt()")
//    public void afterThrowing(){
//        System.out.println("afterThrowing advice");}
}
